/**
 * @file mysql_manager.cpp
 * @brief MySQL数据库管理器的实现
 * @details 负责处理与MySQL数据库的所有交互，包括：
 *          - 数据库连接的建立和维护
 *          - 用户数据的CRUD操作
 *          - 查询执行和结果处理
 *          - 错误处理和日志记录
 */

#include "mysql_manager.hpp"
#include "../config/config.hpp"
#include "../utils/logger.hpp"
#include <cstring>
#include <sstream>
#include <cppconn/prepared_statement.hpp>

MySQLManager& MySQLManager::getInstance() {
    static MySQLManager instance;
    return instance;
}

MySQLManager::~MySQLManager() {
    cleanup();
}

bool MySQLManager::init() {
    try {
        // 从配置文件获取数据库连接参数
        auto& config = Config::getInstance();
        std::string host = config.getMySQLHost();
        std::string user = config.getMySQLUser();
        std::string password = config.getMySQLPassword();
        std::string database = config.getMySQLDatabase();

        // 创建MySQL驱动实例
        driver_ = get_driver_instance();
        
        // 建立数据库连接
        std::stringstream url;
        url << "tcp://" << host << ":3306";
        connection_.reset(driver_->connect(url.str(), user, password));
        connection_->setSchema(database);

        // 初始化预处理语句
        initPreparedStatements();

        Logger::getInstance().info("MySQL connection established successfully");
        return true;
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("MySQL connection failed: {} (MySQL error code: {}, SQLState: {})",
            e.what(), e.getErrorCode(), e.getSQLState());
        return false;
    }
}

void MySQLManager::cleanup() {
    try {
        // 清理所有预处理语句
        create_user_stmt_.reset();
        get_user_by_id_stmt_.reset();
        get_user_by_username_stmt_.reset();
        update_last_login_stmt_.reset();
        validate_credentials_stmt_.reset();

        // 关闭数据库连接
        if (connection_) {
            connection_->close();
            connection_.reset();
        }

        Logger::getInstance().info("MySQL connection closed successfully");
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Error during MySQL cleanup: {}", e.what());
    }
}

void MySQLManager::initPreparedStatements() {
    // 准备创建用户的SQL语句
    create_user_stmt_.reset(connection_->prepareStatement(
        "INSERT INTO users (username, password_hash, email) VALUES (?, ?, ?)"
    ));

    // 准备通过ID查询用户的SQL语句
    get_user_by_id_stmt_.reset(connection_->prepareStatement(
        "SELECT * FROM users WHERE id = ?"
    ));

    // 准备通过用户名查询用户的SQL语句
    get_user_by_username_stmt_.reset(connection_->prepareStatement(
        "SELECT * FROM users WHERE username = ?"
    ));

    // 准备更新最后登录时间的SQL语句
    update_last_login_stmt_.reset(connection_->prepareStatement(
        "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?"
    ));

    // 准备验证用户凭证的SQL语句
    validate_credentials_stmt_.reset(connection_->prepareStatement(
        "SELECT id FROM users WHERE username = ? AND password_hash = ?"
    ));
}

bool MySQLManager::createUser(const std::string& username, const std::string& password, const std::string& email) {
    try {
        // 设置预处理语句参数
        create_user_stmt_->setString(1, username);
        create_user_stmt_->setString(2, password);  // 注意：实际应用中应该使用哈希后的密码
        create_user_stmt_->setString(3, email);

        // 执行插入操作
        create_user_stmt_->execute();
        return true;
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Failed to create user: {} (MySQL error code: {}, SQLState: {})",
            e.what(), e.getErrorCode(), e.getSQLState());
        return false;
    }
}

std::shared_ptr<User> MySQLManager::getUserById(int id) {
    try {
        // 设置查询参数
        get_user_by_id_stmt_->setInt(1, id);
        
        // 执行查询
        std::unique_ptr<sql::ResultSet> result(get_user_by_id_stmt_->executeQuery());
        
        // 处理查询结果
        if (result->next()) {
            return std::make_shared<User>(
                result->getInt("id"),
                result->getString("username"),
                result->getString("email")
            );
        }
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Failed to get user by ID: {}", e.what());
    }
    return nullptr;
}

std::shared_ptr<User> MySQLManager::getUserByUsername(const std::string& username) {
    try {
        // 设置查询参数
        get_user_by_username_stmt_->setString(1, username);
        
        // 执行查询
        std::unique_ptr<sql::ResultSet> result(get_user_by_username_stmt_->executeQuery());
        
        // 处理查询结果
        if (result->next()) {
            return std::make_shared<User>(
                result->getInt("id"),
                result->getString("username"),
                result->getString("email")
            );
        }
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Failed to get user by username: {}", e.what());
    }
    return nullptr;
}

bool MySQLManager::updateUserLastLogin(int userId) {
    try {
        // 更新用户最后登录时间
        update_last_login_stmt_->setInt(1, userId);
        update_last_login_stmt_->execute();
        return true;
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Failed to update last login: {}", e.what());
        return false;
    }
}

bool MySQLManager::validateUserCredentials(const std::string& username, const std::string& password) {
    try {
        // 设置验证参数
        validate_credentials_stmt_->setString(1, username);
        validate_credentials_stmt_->setString(2, password);  // 注意：实际应用中应该使用哈希后的密码
        
        // 执行验证查询
        std::unique_ptr<sql::ResultSet> result(validate_credentials_stmt_->executeQuery());
        
        // 检查是否有匹配的用户记录
        return result->next();
    } catch (sql::SQLException& e) {
        Logger::getInstance().error("Failed to validate credentials: {}", e.what());
        return false;
    }
} 